﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;

namespace XmlVisualizer.DiagramDesigner {
	/// <summary>
	/// Represents a selectable item in the Toolbox.
	/// </summary>
	public class ToolboxItem : ContentControl {
		#region Member fields
		// caches the start point of the drag operation
		private Point? dragStartPoint = null;
		#endregion		

		#region Constructors
		static ToolboxItem() {
			// set the key to reference the style for this control
			FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(
				typeof(ToolboxItem), new FrameworkPropertyMetadata(typeof(ToolboxItem)));
		}
		#endregion	

		#region Event handlers
		/// <summary>
		/// Invoked on PreviewMouseDown.
		/// </summary>
		/// <param name="e">The event data.</param>
		protected override void OnPreviewMouseDown(MouseButtonEventArgs e) {
			base.OnPreviewMouseDown(e);
			this.dragStartPoint = new Point?(e.GetPosition(this));
		}

		/// <summary>
		/// Invoked on MouseMove.
		/// </summary>
		/// <param name="e">The event data.</param>
		protected override void OnMouseMove(MouseEventArgs e) {
			base.OnMouseMove(e);
			if (e.LeftButton != MouseButtonState.Pressed)
				this.dragStartPoint = null;

			if (this.dragStartPoint.HasValue) {
				// XamlWriter.Save() has limitations in exactly what is serialized,
				// see SDK documentation; short term solution only;
				string xamlString = XamlWriter.Save(this.Content);
				DragObject dataObject = new DragObject();
				dataObject.Xaml = xamlString;

				WrapPanel panel = VisualTreeHelper.GetParent(this) as WrapPanel;
				if (panel != null) {
					// desired size for DesignerCanvas is the stretched Toolbox item size
					double scale = 1.3;
					dataObject.DesiredSize = new Size(panel.ItemWidth * scale, panel.ItemHeight * scale);
				}

				DragDrop.DoDragDrop(this, dataObject, DragDropEffects.Copy);

				e.Handled = true;
			}
		}
		#endregion		
	}

	/// <summary>
	/// Wraps info of the dragged object into a class.
	/// </summary>
	public class DragObject {
		#region Properties
		/// <summary>
		/// Gets or sets the string that represents the serialized content.
		/// </summary>
		public String Xaml { get; set; }

		/// <summary>
		/// Gets or sets the width and height of the DesignerItem
		/// when this DragObject is dropped on the DesignerCanvas.
		/// </summary>
		public Size? DesiredSize { get; set; }
		#endregion		
	}
}
